#ifndef CPIR_KEY_H
#define CPIR_KEY_H

#include "common.h"
#include "socket.h"
#include "nalgo.h"
#include "message.h"
#include <stdlib.h> 
#include <stdio.h> 
#include<ctime>
#include<windows.h>

//   Copyright 2011 CPIR Team
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

//RsaKey
class RsaKey 
{
	key_t rsa_d,rsa_e,rsa_n,limit;
public:
	RsaKey(int n);
	int get_d();
	int get_e();
	int get_n();
};

//ServerPublicKey
class ServerPublicKey : public ISerializable 
{
	key_t n, e;
public:
	ServerPublicKey(key_t n, key_t e) : n(n), e(e) {}
	key_t getN() const;
	key_t getE() const;
	const Serialization getSerialization() const;
	static ServerPublicKey* fromRaw(Serialization s);
};

//RabinServerKey
class RabinServerKey {
	key_t d;  
	ServerPublicKey* pubkey;

	RabinServerKey(int32_t dd,int32_t n,int32_t e);
public:
	~RabinServerKey();
	const ServerPublicKey* getPublic() const;
	CipherMessage* encrypt(const Message* m,const Message* x,const CipherMessage* v) const; //Step 6 & Step 7:k_n = (v - x_n)^d mod N,m_n' = m_n + k_n 
	static RabinServerKey* fromRandom(int N);  
};

//ClientKey
class ClientKey 
{
	key_t k;
public: 
	ClientKey(key_t k): k(k) {}
	CipherMessage* coencrypt(const Message* msg, const ServerPublicKey* pubkey) const;      //Step 5:v = (x_b + k^e) mod N
	Message* decrypt(const CipherMessage* cmsg) const;                                      //Step 8:m_b = m_b' - k
	static ClientKey* fromRandom();
};

#endif
